﻿using Common;
using HslCommunication.Profinet.Siemens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoneLine.Models;
using ZoneLine.Stations;

namespace ZoneLine.Stations
{
    /// <summary>
    /// 工站基类
    /// </summary>
    public abstract class WorkStationDBase : WorkStationBase
    {
        #region Fields
        /// <summary>
        /// 工作方向地址（左、右）
        /// </summary>
        public string WorkDirectionAddr { get; set; }
        /// <summary>
        /// 产品类型地址(LX、SQ...)
        /// </summary>
        public string CurrentProductTypeAddr { get; set; }
        /// <summary>
        /// 配方名地址（X04、W04）
        /// </summary>
        public string FormulaNameAddr { get; set; }
        /// <summary>
        /// 产品类型（L、R）
        /// </summary>
        public string CurrentProductModelAddr { get; set; }


        /// <summary>
        /// 配方地址
        /// </summary>
        public string FormulaAddr { get; set; }



        public string AllowWorkAddr { get; set; }

        protected string _startAddr = string.Empty;

        protected ushort _readLength = 0;

        #endregion

        static WorkStationDBase()
        {
            HslCommunication.Authorization.SetAuthorizationCode("b980977c-3323-4876-b633-c0bef93d75c1");
        }


        #region Props

        private string _stationCode;

        public string StationCode
        {
            get { return _stationCode; }
            set => SetProperty(ref _stationCode, value);
        }

        private bool _heart;

        public bool Heart
        {
            get { return _heart; }
            set { _heart = value; }
        }

        private bool _startUploadCode;

        public bool StartUploadCode
        {
            get { return _startUploadCode; }
            set => SetProperty(ref _startUploadCode, value);
        }

        private bool _startUploadData;

        public bool StartUploadData
        {
            get { return _startUploadData; }
            set => SetProperty(ref _startUploadData, value);
        }

        private bool _heartToPlc;

        public bool HeartToPlc
        {
            get { return _heartToPlc; }
            set => SetProperty(ref _heartToPlc, value);
        }

        public string HeartToPlcAddr { get; set; }

        private bool _endUpLoadCode;

        public bool EndUpLoadCode
        {
            get { return _endUpLoadCode; }
            set => SetProperty(ref _endUpLoadCode, value);
        }

        public string EndUpLoadCodeAddr { get; set; }

        private bool _endUpLoadData;

        public bool EndUpLoadData
        {
            get { return _endUpLoadData; }
            set => SetProperty(ref _endUpLoadData, value);
        }

        public string EndUpLoadDataAddr { get; set; }

        private int _allowWork;

        public int AllowWork
        {
            get { return _allowWork; }
            set => SetProperty(ref _allowWork, value);
        }

        #endregion

        #region Methods
        private int collectDataCut = 0;
        protected override void CollectData()
        {
            try
            {

                collectDataCut++;
                _logger.Debug($"在{CurrentStationName}开始采集{collectDataCut}");

                if (string.IsNullOrEmpty(_startAddr) || _readLength < 1)
                {
                    return;
                }
                if (_client == null)
                {
                    _client = new SiemensS7Net(SiemensPLCS.S1200);
                    _client.IpAddress = Ip;
                    _client.SetPersistentConnection();
                    _client.Port = Port;
                    PropertyChanged += SignalAction;
                }
                var readRlt = _client.Read(_startAddr, _readLength);

                _logger.Debug($"在{CurrentStationName}采集结果{collectDataCut}，{readRlt.IsSuccess}");

                ConnectState = readRlt.IsSuccess;
                try
                {
                    WriteData(HeartToPlcAddr, HeartToPlc == true ? (short)0 : (short)1, isRepeat: true, isHeart: true);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
                if (readRlt.IsSuccess)
                {
                    //要先解析数据，在解析控制信号
                    DealData(readRlt.Content);
                    DealDataCommon(readRlt.Content);
                }
                else
                {
                    ConnectState = false;
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "read data err");
            }
        }

        protected override void DealDataCommon(byte[] content)
        {
            //StationCode = GetPlcString(content, 0);
            Heart = _client.ByteTransform.TransInt16(content, 8) == (short)1;
            StartUploadCode = _client.ByteTransform.TransInt16(content, 6) == (Int16)1;
            StartUploadData = _client.ByteTransform.TransInt16(content, 10) == (Int16)1;

            HeartToPlc = _client.ReadInt16("DB1001.DBW0").Content == (Int16)1;
            EndUpLoadCode = _client.ReadInt16("DB1001.8").Content == (Int16)1;
            EndUpLoadData = _client.ReadInt16("DB1001.2").Content == (Int16)1;
            AllowWork = _client.ReadInt16("DB1001.8").Content;
        }

        protected string GetPlcString(byte[] content, short index)
        {
            byte length = content[index + 1];
            return _client.ByteTransform.TransString(content, index + 2, length, Encoding.ASCII).Replace("\r", "").Replace("\n", "");
        }

        protected void UpdateBeforeStationCode(string absCode, string qrCode)
        {
            Task.Run(() =>
            {
                _dal.UpdateModel<QOP006StationResult>(p => p.AbsScanCode == absCode, p => new QOP006StationResult { Code = qrCode });
                _dal.UpdateModel<QOP010StationResult>(p => p.AbsScanCode == absCode, p => new QOP010StationResult { Code = qrCode });
                _dal.UpdateModel<QOP020StationResult>(p => p.AbsScanCode == absCode, p => new QOP020StationResult { Code = qrCode });
            });
        }


        /// <summary>
        /// 初始化复位地址
        /// </summary>
        /// <returns></returns>
        protected void InitReSetAddr()
        {
            _ = Task.Run(async () =>
            {
                while (!ConnectState)
                {
                    LogWithUi(_logUiChannel, $"在{CurrentStationName}正在等待设备连接，res={ConnectState}");
                    await Task.Delay(500);
                }
                var res1 = WriteData(EndUpLoadCodeAddr, 0, isRepeat: true);
                LogWithUi(_logUiChannel, $"在{CurrentStationName}初始化，复位上传条码完成指令，res={res1}");
                var res2 = WriteData(AllowWorkAddr, 0, isRepeat: true);
                LogWithUi(_logUiChannel, $"在{CurrentStationName}初始化，复位工作控制指令，res={res2}");
                var res3 = WriteData(EndUpLoadDataAddr, 0, isRepeat: true);
                LogWithUi(_logUiChannel, $"在{CurrentStationName}初始化，复位数据记录指令，res={res3}");
            });
        }
        #endregion
    }
}